package com.turnengine.client.local.unit.list;

import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class ParentUnit implements IParentUnit, Comparable<IParentUnit> {

	private final int unitId;
	private final Map<Integer, IChildUnit> unitIdToChildMap = new TreeMap<Integer, IChildUnit>();

	public ParentUnit(int unitId) {
		if (unitId < 0) {
			throw new IllegalArgumentException("unitId=" + unitId);
		}
		this.unitId = unitId;
	}

	@Override
	public int getUnitId() {
		return unitId;
	}

	@Override
	public int children() {
		return unitIdToChildMap.size();
	}

	@Override
	public boolean hasChildren() {
		return children() > 0;
	}

	@Override
	public IChildUnit getChild(int unitId) {
		return unitIdToChildMap.get(unitId);
	}

	@Override
	public long getChildAmount(int unitId) {
		IChildUnit unit = unitIdToChildMap.get(unitId);
		return unit == null ? 0 : unit.getAmount();
	}

	@Override
	public boolean containsChild(int unitId) {
		return getChildAmount(unitId) > 0;
	}

	@Override
	public Collection<IChildUnit> getChildren() {
		return unitIdToChildMap.values();
	}

	@Override
	public void setChildAmount(int unitId, long amount) {
		if (amount == 0) {
			unitIdToChildMap.remove(unitId);
		} else {
			IChildUnit unit = new ChildUnit(unitId, amount);
			unitIdToChildMap.put(unitId, unit);
		}
	}

	@Override
	public void addChild(IChildUnit child) {
		int unitId = child.getUnitId();
		IChildUnit unit = unitIdToChildMap.get(unitId);
		if (unit == null) {
			unitIdToChildMap.put(unitId, child);
		} else {
			unit.addAmount(child.getAmount());
		}
	}

	@Override
	public String toString() {
		ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
		builder.append(unitId);
		builder.append(unitIdToChildMap);
		return builder.toString();
	}

	@Override
	public boolean equals(Object object) {
		if (object == this) {
			return true;
		}
		if (object instanceof ParentUnit) {
			ParentUnit unit = (ParentUnit) object;
			EqualsBuilder equals = new EqualsBuilder();
			equals.append(this.unitId, unit.unitId);
			equals.append(this.unitIdToChildMap, unit.unitIdToChildMap);
			return equals.isEquals();
		}
		return false;
	}

	@Override
	public int compareTo(IParentUnit unit) {
		if (this.getUnitId() != unit.getUnitId()) {
			return this.getUnitId() < unit.getUnitId() ? -1 : 1;
		}
		return hasChildren() ? 1 : -1;
	}

}
